<template>
  <div class="channel-edit">
    <!-- 当前登陆用户已经订阅的频道 -->
    <div class="channel">
      <van-cell title="我的频道" :border="false">
        <van-button @click="editing = !editing" size="mini" type="info"
          >编辑</van-button
        >
      </van-cell>
      <van-grid>
        <!-- 这里之所以可以用index是因为 首页的频道列表和我的频道用的一套数据 小技巧
        通过加类名来修改样式
        -->
        <van-grid-item
          v-for="(item, index) in myChannels"
          :key="item.id"
          :class="{ cur: channelIndex === index }"
        >
          <span @click="chooseChannel(index)">{{ item.name }}</span>
          <van-icon
            v-show="editing"
            @click="hRemoveChannel(index)"
            name="cross"
            class="btn"
          ></van-icon>
        </van-grid-item>
      </van-grid>
    </div>
    <!-- 当前登陆用户没有订阅的频道 -->
    <div class="channel">
      <van-cell title="可选频道" :border="false"></van-cell>
      <van-grid>
        <van-grid-item
          @click="hAddChannel(item)"
          v-for="item in removeChannel"
          :key="item.id"
        >
          <span>{{ item.name }}</span>
        </van-grid-item>
      </van-grid>
    </div>
  </div>
</template>

<script>
import { allChannels, addChannel, delChannel } from "@/api/channel.js";
export default {
  name: "ChannelEdit",
  props: {
    //因为myChannels 公用的一个数组的数据 所以可以通过索引值来进行判断
    myChannels: {
      type: Array
    },
    //父组件传过来的当前高亮的索引值,从而改变频道列表的当前频道的样式
    channelIndex: {
      type: Number
    }
  },
  data() {
    return {
      allChannels: [],
      editing: false //我的频道里的频道是否处于编辑状态
    };
  },
  computed: {
    //删选所有频道里的频道  推荐频道=所有频道-我的频道
    removeChannel() {
      //1.filter
      //filter()把传入的函数依次作用于每个元素，然后根据返回值是true还是false决定保留还是丢弃该元素。
      let res = this.allChannels.filter(item => {
        //2.findIndex 找到我的频道对象的id  相同的我们不要  不同的我们要
        const myChannel = this.myChannels;
        //找到索引值  -1 没有 >-1 有
        const idx = myChannel.findIndex(myitem => {
          return myitem.id === item.id; //不写 {} return 可以不写
        });
        if (idx > -1) {
          //找到
          return false;
        } else {
          //找不到
          return true;
        }
      });
      console.log(res, "筛选后的频道");
      return res;
    }
  },
  created() {
    this.getAllChannels();
  },
  methods: {
    async getAllChannels() {
      try {
        const res = await allChannels();
        this.allChannels = res.data.data.channels;
      } catch (error) {
        console.log(error);
      }
    },
    //点击频道跳转 val就是数组的下标
    chooseChannel(val) {
      //1.通过emit 将子组件中的值传出去给父组件
      this.$emit("changeChannel", val);
    },
    //子组件中数组添加/删除影响父组件中数组
    //// 结论：如果从父组件中传入的props是引用数据类型(数组，对象),则在子组件中可以通过数组提供的api(push,slice......)
    // 来间接修改props，从而达到在子组件中修改数据同时作用到父组件中
    //引用类型数据栈中存的是内存地址，堆中存放数据，如果执行赋值操作，拷贝的是地址，所以指向同一份数据，一改全改
    //添加我的频道，从可选频道中选取
    async hAddChannel(obj) {
      // console.log(this.myChannels);//[{id:xxx,name:""}]
      //1.修改要发送给服务器的数据格式
      const channels = [...this.myChannels, obj];
      const newChannels = [];
      channels.map((item, idx) => {
        newChannels.push({
          id: item.id,
          seq: idx
        });
      });
      // console.log(newChannels);//[{id:xxx,seq:xxx}]
      newChannels.splice(0, 1); //去除推荐频道，因为推荐频道总在第一个，所以直接删除
      try {
        //2.把修改好的数据格式和内容发给后端
        await addChannel(newChannels);
        //3.成功之后给个提示
        this.$toast("添加成功");
        //4.把要添加的频道内容添加到我的频道中去*****
        /* 
      原理：计算属性可以实时的计算我们数据的变化，把变化后的数据
        */
        this.myChannels.push(obj);
      } catch {
        //5.服务器响应失败，给个提示
        this.$toast("添加失败");
      }
    },
    //删除我的频道
    async hRemoveChannel(idx) {
      //处理数据
      if (idx === 0) {
        return;
      }
      try {
        //服务器。。。
        //调用服务器接口
        const val = Number(this.myChannels[idx].id);
        await delChannel(val); //传入的参数是一个[ number ]
        this.$toast("删除成功");
        //原理 splice(idx,1)
        //接收一个索引值就行
        this.myChannels.splice(idx, 1);
        //1.删除频道成功之后
        //2.判断父组件那边的 active 索引值是不是大于我们删除的索引值
        if (this.channelIndex > idx) {
          //this.channelIndex-1
          //1.2 通知父组件  或者通过  input 和 v-model
          this.$emit("deleteChannel", this.channelIndex - 1);
        }
      } catch {
        this.$toast("删除失败");
      }
    }
  }
};
</script>

<style lang="less" scoped>
.channel-edit {
  .channel {
    padding: 15px;
    font-size: 12px;
  }
  .btn {
    position: absolute;
    top: 0;
    right: 0;
    font-size: 10px;
  }
  // 高亮显示
  .cur {
    color: red;
    font-weight: bold;
  }
}
</style>
